﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Use this for morphological Elements to create a structured element kernel...
    /// </summary>
	public class StructuringElements
	{
        private int m_nWidth = 2;
        private int m_nHeight = 2;
        private double m_dDegree = 0.0f;

        private int[,] m_aKernel = null;

        public void Square(int _nWidth)
        {
            m_nHeight = _nWidth;
            m_nWidth = _nWidth;
            int[,] aKernel = new int[m_nWidth, m_nHeight];
            for (int y = 0; y < m_nHeight; y++)
            {
                for (int x = 0; x < m_nWidth; x++)
                {
                    aKernel[x, y] = 1;
                }
            }
        }

        public int Height
        {
            get { return m_nHeight; }
        }

        public int Width
        {
            get { return m_nWidth; }
        }

        public void Random(int _nWidth, int _nHeight)
        {
            m_nWidth = _nWidth;
            m_nHeight = _nHeight;
            int nRandSeed = DateTime.Now.Millisecond*this.GetHashCode();
            for (int y = 0; y < m_nHeight; y++)
            {
                for (int x = 0; x < m_nWidth; x++)
                {
                    m_aKernel[x, y] = new Random(nRandSeed).Next(0, 1);
                }
            }
        }


        /// <summary>
        /// Shift elements by given Vector (nx, ny)
        /// </summary>
        /// <param name="nX"></param>
        /// <param name="nY"></param>
        public void Translate(int nX, int nY)
        {
            int[,] aKernel = CopyKernel();

            for (int y = 0; y < m_nHeight; y++)
            {
                for (int x = 0; x < m_nWidth; x++)
                {
                    m_aKernel[x, y] = aKernel[x + nX, y + nY];
                }
            }
        }

        protected int[,] CopyKernel()
        {
            int[,] aKernel = new int[m_nWidth, m_nHeight];
            for (int y = 0; y < m_nHeight; y++)
            {
                for (int x = 0; x < m_nWidth; x++)
                {
                    m_aKernel[x, y] = aKernel[x, y];
                }
            }
            return aKernel;
        }

        //SE2 = reflect(SE) reflects a structuring element through its center. 
        //The effect is the same as if you rotated the structuring element's domain 180 degrees around its center (for a 2-D structuring element). If SE is an array of structuring element objects
        //, then reflect(SE) reflects each element of SE, and SE2 has the same size as SE.
        public void Reflect()
        {
            int[,] aKernel = CopyKernel();
            for (int y = 0; y < m_nHeight; y++)
            {
                for (int x = 0; x < m_nWidth; x++)
                {
                    m_aKernel[x, y] = aKernel[m_nHeight - x, m_nWidth - y];
                }
            }
        }

        public int[,] Kernel
        {
            get { return m_aKernel; }
        }

        public void Diamond(int _nRadius)
        {
        }

        public void Line(int _nLen, double _dDegree)
        {
        }

        public void Octagon(int _nRadius)
        {
        }

        public void Disk(int _nRadius)
        {
        }

        public void Ball(int _nR, int _nHeight)
        {
        }

        public void PeriodicLine()
        {
        }

        /// <summary>
        /// nX and nY specifies the offset
        /// </summary>
        /// <param name="_nX"></param>
        /// <param name="_nY"></param>
        public void Pair(int _nX, int _nY)
        {
            m_aKernel[0, 0] = 1;
            m_aKernel[0 + _nX, 0 + _nY] = 1;
        }

        public void Arbitrary()
        {
        }
	}
}
